module ActionView
  module Helpers
    module PrototypeHelper
      def form_remote_tag(options = {})
        options[:form] = true
        
        options[:html] ||= {}
        options[:html][:onsubmit] = "#{remote_function(options)}; return false;"
        options[:html][:action] = options[:html][:action] || url_for(options[:url])
        options[:html][:method] = options[:html][:method] || options[:method] || "post"
        
        tag("form", options[:html], true)
      end
    end
    
    module FormHelper
      def form_for_with_labels(object_name, *args, &proc)
        raise ArgumentError, "Missing block" unless block_given?
        options = args.last.is_a?(Hash) ? args.pop : {}
        options[:builder] = LabellingFormBuilder
        concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}), proc.binding)
        fields_for(object_name, *(args << options), &proc)
        concat('</form>', proc.binding)
      end

      alias_method_chain :form_for, :labels
    end

    class LabellingFormBuilder < FormBuilder
      (field_helpers - %w(check_box radio_button)).each do |selector|
        src = <<-end_src
          def #{selector}(method, options = {})
            label = options.delete(:label) || method.to_s.humanize
            if example = options.delete(:example)
              label << ' (e.g. <em>' + example + '</em>)'
            end
            
            '<div class="label"><label for="' + @object_name.to_s + '_' + method.to_s + '">' + label + '</label>:</div><div class="input">' + @template.send(#{selector.inspect}, @object_name, method, options.merge(:object => @object)) + '</div>'
          end
        end_src
        class_eval src, __FILE__, __LINE__
      end

      def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
        label = options.delete(:label) || method.to_s.humanize
        if example = options.delete(:example)
          label << ' (e.g. <em>' + example + '</em>)'
        end
        %Q{<div class="field"><div class="label"><label for="#{@object_name}_#{method}">} +
        @template.check_box(@object_name, method, options.merge(:object => @object), checked_value, unchecked_value) +
        "#{label}</label></div></div>"
      end

      def radio_button(method, tag_value, options = {})
        label = options.delete(:label) || method.to_s.humanize
        if example = options.delete(:example)
          label << ' (e.g. <em>' + example + '</em>)'
        end
        
        %Q{<div class="field"><div class="label"><label for="#{@object_name}_#{method}">#{label}</label>:</div><div class="input">} + 
        @template.radio_button(@object_name, method, tag_value, options.merge(:object => @object)) + "</div></div>"
      end
      
      def submit(value = 'Save', name='commit')
        %Q{<div class="field"><input type="submit" name="#{name}" value="#{value}" /></div>}
      end
    end
  end
end